<template lang="html">
	<div class="yo-scroll" :class="{'down':(state===0),'up':(state==1),refresh:(state===2),touch:touching}" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)" @scroll="(onInfinite || infiniteLoading) ? onScroll($event) : undefined">
		<section class="inner" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)' }">
			<header class="pull-refresh">
				<slot name="pull-refresh">
					<span class="down-tip">下拉更新</span>
					<span class="up-tip">松开更新</span>
					<span class="refresh-tip">更新中...</span>
				</slot>
			</header>
			<slot></slot>
			<footer class="load-more">
				<slot name="load-more">
					<span @click="infinite">{{loadmoreText}}</span>
				</slot>
			</footer>
		</section>
	</div>
</template>

<script>
	export default {
		props: {
			offset: {
				type: Number,
				default: 40
			},
			enableInfinite: {
				type: Boolean,
				default: true
			},
			enableRefresh: {
				type: Boolean,
				default: true
			},
			//下拉刷新
			onRefresh: {
				type: Function,
				default: undefined,
				required: false
			},
			//上拉加载
			onInfinite: {
				type: Function,
				default: undefined,
				require: false
			}
		},
		data() {
			return {
				top: 0,
				state: 0,
				startY: 0,
				touching: false,
				infiniteLoading: false,
				loadmoreText: "加载更多"
			}
		},
		methods: {
			setLoadMoreText(str) {
				this.loadmoreText = str 
			},
			touchStart(e) {
				this.startY = e.targetTouches[0].pageY
				this.startScroll = this.$el.scrollTop || 0
				this.touching = true
			},
			touchMove(e) {
				if(!this.enableRefresh || this.$el.scrollTop > 0 || !this.touching) {
					return
				}
				let diff = e.targetTouches[0].pageY - this.startY - this.startScroll
				if(diff > 0) e.preventDefault()
				this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)

				if(this.state === 2) { // in refreshing
					return
				}
				if(this.top >= this.offset) {
					this.state = 1
				} else {
					this.state = 0
				}
			},
			touchEnd(e) {
				if(!this.enableRefresh) return
				this.touching = false
				if(this.state === 2) { // in refreshing
					this.state = 2
					this.top = this.offset
					return
				}
				if(this.top >= this.offset) { // do refresh
					this.refresh()
				} else { // cancel refresh
					this.state = 0
					this.top = 0
				}
			},
			refresh() {
				this.state = 2
				this.top = this.offset
				this.onRefresh(this.refreshDone)
			},
			//上拉刷新结束回调
			refreshDone() {
				this.state = 0
				this.top = 0
			},
			infinite() {
				this.infiniteLoading = true
				this.onInfinite(this.infiniteDone)
			},
			//下拉加载结束回调
			infiniteDone() {
				this.infiniteLoading = false
			},
			onScroll(e) {
				if(!this.enableInfinite || this.infiniteLoading) {
					return
				}
				let outerHeight = this.$el.clientHeight
				let innerHeight = this.$el.querySelector('.inner').clientHeight
				let scrollTop = this.$el.scrollTop
				let ptrHeight = this.onRefresh ? this.$el.querySelector('.pull-refresh').clientHeight : 0
				let infiniteHeight = this.$el.querySelector('.load-more').clientHeight
				let bottom = innerHeight - outerHeight - scrollTop - ptrHeight
				if(bottom < infiniteHeight) {
					this.infinite()
				}
				console.log(bottom, infiniteHeight)
			}
		}
	}
</script>
<style>
	.yo-scroll {
		position: relative;
		/*overflow: auto;*/
		-webkit-overflow-scrolling: touch;
	}
	
	.yo-scroll .inner {
		position: relative;
		top: -1rem;
		transition-duration: 300ms;
	}
	
	.yo-scroll .pull-refresh {
		position: relative;
		height: 1rem;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	
	.yo-scroll .load-more span {
		line-height: 0.6rem;
		height: 0.6rem;
		margin-bottom: 0.2rem;
	}
	
	.pull-refresh span, .load-more span {
		padding: 0 0.2rem;
		color: #666;
	}
	
	.yo-scroll.touch .inner {
		transition-duration: 0ms;
	}
	
	.yo-scroll.down .down-tip {
		display: block;
	}
	
	.yo-scroll.up .up-tip {
		display: block;
	}
	
	.yo-scroll.refresh .refresh-tip {
		display: block;
	}
	
	.yo-scroll .down-tip,
	.yo-scroll .refresh-tip,
	.yo-scroll .up-tip {
		display: none;
	}
	
	.yo-scroll .load-more {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
		bottom: -1.1rem;
		width: 100%;
	}
</style>